package nf.util;

import java.util.*;

public abstract class FilteringIterator<T> implements Iterator<T>
{
	private Iterator<? extends T> inner;
	private T cache;
	
	public FilteringIterator(Iterator<? extends T> inner)
	{
		this.inner = inner;
		cache = null;
	}
	
	private T getNextItem()
	{
		while (inner.hasNext()) {
			T item = inner.next();
			
			if (accept(item)) {
				return item;
			}
		}
		
		throw new NoSuchElementException();
	}
	
	public boolean hasNext()
	{
		if (cache != null) {
			return true;
		} else {
			try {
				cache = getNextItem();
				return true;
			} catch (NoSuchElementException e) {
				return false;
			}
		}
	}
	
	public T next()
	{
		if (cache != null) {
			T value = cache;
			cache = null;
			return value;
		}
		
		return getNextItem();
	}
	
	public void remove()
	{
		inner.remove();
	}
	
	protected abstract boolean accept(T value);
}
